package com.sinopec.basemodule.http

import android.net.ParseException

import com.google.gson.JsonParseException
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException
import com.sinopec.basemodule.BaseApplication
import com.sinopec.basemodule.R
import com.sinopec.basemodule.common.Logger

import org.apache.http.conn.ConnectTimeoutException
import org.json.JSONException

import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.net.ssl.SSLHandshakeException

/**
 * Created by ronny on 2018/3/22.
 */

class ExceptionEngine {
    /**
     * 约定异常
     */
    object ERROR {
        /**
         * 未知错误
         */
        const val UNKNOWN = 1000

        /**
         * 解析错误
         */
        const val PARSE_ERROR = 1001

        /**
         * 网络错误
         */
        const val NETWORD_ERROR = 1002

        /**
         * 协议出错
         */
        const val HTTP_ERROR = 1003

        /**
         * 证书出错
         */
        const val SSL_ERROR = 1005

        /**
         * 连接超时
         */
        const val TIMEOUT_ERROR = 1006
    }

    class ResponseThrowable @JvmOverloads constructor(
        throwable: Throwable,
        var code: Int,
        override var message: String? = null
    ) : Exception(message, throwable)

    companion object {
        private const val UNAUTHORIZED = 401
        private const val FORBIDDEN = 403
        private const val NOT_FOUND = 404
        private const val REQUEST_TIMEOUT = 408
        private const val INTERNAL_SERVER_ERROR = 500
        private const val BAD_GATEWAY = 502
        private const val SERVICE_UNAVAILABLE = 503
        private const val GATEWAY_TIMEOUT = 504

        @JvmStatic
        fun handleException(e: Throwable): ResponseThrowable {
            val ex: ResponseThrowable
            Logger.e(e.toString())
            when (e) {
                is HttpException -> {
                    ex = ResponseThrowable(e, ERROR.HTTP_ERROR)
                    when (e.code()) {
                        UNAUTHORIZED,
                        FORBIDDEN,
                        REQUEST_TIMEOUT,
                        GATEWAY_TIMEOUT,
                        INTERNAL_SERVER_ERROR,
                        BAD_GATEWAY,
                        SERVICE_UNAVAILABLE -> ex.message = BaseApplication.getInstance().getString(R.string.error_net)
                        else -> ex.message = e.message
                    }
                    return ex
                }
                is retrofit2.HttpException -> {
                    ex = ResponseThrowable(e, ERROR.HTTP_ERROR)
                    when (e.code()) {
                        UNAUTHORIZED,
                        FORBIDDEN,
                        REQUEST_TIMEOUT,
                        GATEWAY_TIMEOUT,
                        INTERNAL_SERVER_ERROR,
                        BAD_GATEWAY,
                        SERVICE_UNAVAILABLE -> ex.message =
                            BaseApplication.getInstance().getString(R.string.error_net)
                        else -> ex.message = e.message
                    }
                    return ex
                }
                is ServerException -> {
                    ex = ResponseThrowable(e, e.code)
                    ex.message = e.msg
                    return ex
                }
                is JsonParseException,
                is JSONException,
                is ParseException -> {
                    ex = ResponseThrowable(e, ERROR.PARSE_ERROR)
                    ex.message = "解析错误"
                    return ex
                }
                is ConnectException -> {
                    ex = ResponseThrowable(e, ERROR.NETWORD_ERROR)
                    ex.message = "连接失败"
                    return ex
                }
                is SSLHandshakeException -> {
                    ex = ResponseThrowable(e, ERROR.SSL_ERROR)
                    ex.message = "证书验证失败"
                    return ex
                }
                is ConnectTimeoutException,
                is SocketTimeoutException -> {
                    ex = ResponseThrowable(e, ERROR.TIMEOUT_ERROR)
                    ex.message = "连接超时"
                    return ex
                }
                else -> {
                    ex = ResponseThrowable(e, ERROR.UNKNOWN)
                    ex.message = "网络异常，请打开百度测试网络！"
                    return ex
                }
            }
        }
    }
}
